package net.vsame.url2sql.web.bigpipe;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.vsame.url2sql.web.Url2SqlFilter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;

/**
 * 2012-8-31 下午8:26:31
 * 
 * @author <a href="mailto:gaollg@sina.com">Gaollg</a>
 */
public class BigpipeHandler {
	private static String encoding = Url2SqlFilter.getEncoding();//配置
	private static List<String> allActionUrls;
	static String realPath = null;
	
	public void handle(String target, HttpServletRequest request,
			HttpServletResponse response, boolean[] isHandled) {
		//初始化
		init(request, response);
		PrintWriter out = null;
		boolean html = target.endsWith(".html");
		String[] parent = new String[]{""};
		if (html){
			//只输出html内容
			File f = new File(realPath + target);
			if(f.exists() && f.isFile()){
				out = printHtml(request, response, f, getParentPath(target), false);
				out.flush();
				isHandled[0] = true;
			}
			return ;
		}
		
		File f = actionHtml(target, parent);
		//其它... 输出html
		if(f != null){
			out = printHtml(request, response, f, parent[0], true);
		}
		
		//处理url...
		boolean json = target.endsWith(".json");
		boolean jsonp = target.endsWith(".jsonp");
		if (json){
			target = target.substring(0, target.length() - 5);
		}
		else if (jsonp){
			target = target.substring(0, target.length() - 6);
		}
		
		//如果包含action 则进入
		if(getActionPath(target) != null){
			if(!BigpipeDataHelper.hasError()){
				//next
			}
		}else{
			BigpipeDataHelper.put404();
		}
		
		if(json || jsonp){
			response.setContentType("application/x-javascript; charset="+encoding);
			try {
				out = response.getWriter();
				if(json){
					out.print(getJosn());
				}else{
					out.print(getJosnp(request));
				}
				out.flush();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
			isHandled[0] = true;
		}
		else if(out != null){
			out.println("<script type=\"text/javascript\">");
			out.println(getJosnp(request));
			out.print("</script></html>");
			out.flush();
			isHandled[0] = true;
		}
		BigpipeDataHelper.remove();
	}

	/**
	 * 初始化
	 * @param request
	 * @param response
	 */
	private void init(HttpServletRequest request, HttpServletResponse response) {
		/*
		try {
			request.setCharacterEncoding(encoding);
			response.setCharacterEncoding(encoding);
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
		*/
		if(allActionUrls == null){
			String contextPath = request.getContextPath();
			if(BigPipeHelper.getCSSBase() == null){
				BigPipeHelper.setCSSBase(contextPath);
			}
			if(BigPipeHelper.getJSBase() == null){
				BigPipeHelper.setJSBase(contextPath);
			}
			if(BigPipeHelper.getIMAGEBase() == null){
				BigPipeHelper.setIMAGEBase(contextPath);
			}
			BigPipeHelper.contentPath = contextPath;
		}
		realPath = request.getSession().getServletContext().getRealPath("");
	}
	
	/**
	 * 输出Jsonp数据,如:
	 * <p>;callback(json);<p/>
	 * @param invocation
	 * @return 
	 */
	private String getJosnp(HttpServletRequest request){
		String method = request.getParameter("callback");
		method = method == null ? "callback" : method;
		String str = ";" + method + "(";
		return str + getJosn() + ");";
	}

	/**
	 * 输出json
	 * @param invocation
	 * @return 
	 */
	private String getJosn() {
		return JSON.toJSONString(BigpipeDataHelper.map(), SerializerFeature.WriteDateUseDateFormat);
	}
	
	private File getFile(String basepath, String url, String[] path){
		File f = new File(basepath + url);
		if(f.exists() && f.isDirectory()){
			File file = new File(f, "index.html");
			path[0] = url;
			if(file.exists() && file.isFile()){
				return file;
			}
		}else{
			File file = new File(basepath + url + ".html");
			if(file.exists() && file.isFile()){
				path[0] = getParentPath(url);
				return file;
			}
		}
		return null;
	}
	
	private String getParentPath(String url){
		int i = url.lastIndexOf("/");
		return url.substring(0, i);
	}
	
	/**
	 * 取得action的请求地址
	 * @param url
	 * @return
	 */
	private String getActionPath(String url){
		String realPath = null;
		if(allActionUrls.contains(url)){
			realPath = url;
		}else{
			int i = url.lastIndexOf("/");
			if(i != -1){
				String temp = url.substring(0, i);
				if(allActionUrls.contains(temp)){
					realPath = temp;
				}
			}
		}
		return realPath;
	}
	
	/**
	 * 取得action对应的html
	 * @param basepath
	 * @param target
	 * @return
	 */
	private File actionHtml(String target, String[] parent){
		if (target.indexOf(".") != -1) {
			return null;
		}
		File file = null;
		
		//先从action中找
		String temp = getActionPath(target);
		if(temp != null){
			file = getFile(realPath, temp, parent);
		}else{
			//action中无, 考虑.html文件是否存在
			file = getFile(realPath, target, parent);
		}
		return file;
	}
	
	/**
	 * 输出html
	 * @param request
	 * @param response
	 * @param path
	 * @param file
	 */
	private PrintWriter printHtml(HttpServletRequest request,
			HttpServletResponse response, File file, String parent, boolean endBody) {
		response.setContentType("text/html; charset=" + encoding);
		PrintWriter out = null;
		try {
			out = response.getWriter();
			out.println(BigPipeHelper.readHtml(file, parent, endBody));
			out.println(BigPipeHelper.getCommScript(request, response));
			out.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return out;
	}
}

